<template>
  <el-container>
    <el-header>
      <div style="display: flex">
        <logo :height="60" />
        <div class="top-title">欢迎使用组态设计器</div>
        <div style="display: flex; align-items: center; margin-left: 20px">
          <el-button type="primary" @click="writeJson" size="large"
            >输出json</el-button
          >
        </div>
      </div>
    </el-header>
    <el-container>
      <el-aside width="300px">
        <tools
          @itemdblclick="handleToolItemDblClick"
          @itemdragstart="handleToolItemDragStart"
        />
      </el-aside>
      <el-main>
        <div class="scale-ruler">
          <vue-ruler-tool
            v-model="ruler.presetLine"
            :step-length="20"
            :parent="true"
            :is-scale-revise="true"
            :visible.sync="ruler.visible"
          >
            <div>
              <span>选择:</span>
              <span>
                {{ selectedShapeId }}
              </span>
              <span>锚点:</span>
              <span>
                {{ selectedAnchorIndex }}
              </span>
            </div>
            <div>
              <span>区域选择</span><span> {{ selectionRectangle }}</span>
            </div>
            <div>
              <span>多选Id列表</span><span> {{ rangeSelectedIdList }}</span>
            </div>
            <div>
              <el-button
                icon="el-icon-bottom-left"
                type="primary"
                @click="goBack"
                >后退</el-button
              >
              <el-button
                icon="el-icon-bottom-right"
                type="primary"
                @click="goFront"
                >前进</el-button
              >
            </div>
            <div :class="`scada-canvas scale-${this.zoom}`">
              <v-stage
                ref="stage"
                :config="configKonva"
                @mousedown="handleStageMouseDown"
                @touchstart="handleStageMouseDown"
                @mouseup="handleStageMouseUp"
                @touchend="handleStageMouseUp"
                @mousemove="handleStageMouseMove"
                @contextmenu="handleStageContextMenu"
              >
                <v-layer ref="background-layer">
                  <v-rect
                    :config="{
                      x: 0,
                      y: 0,
                      fill: stageConfig.bgConfig.bgColor,
                      width: configKonva.width,
                      height: configKonva.height,
                      draggable: false,
                      listening: false,
                    }"
                  >
                  </v-rect>
                </v-layer>
                <v-layer ref="layer" :config="{ xClass: 'XLayer' }">
                  <component
                    @events="handleSElementEvents"
                    @mouseenter="handleSElementMoveEnter"
                    @mouseleave="handleSElementMoveLeave"
                    @dragend="handleSElementDragend"
                    @transformend="handleSElementTransformEnd"
                    :is="item.xType"
                    v-for="item in stageConfig.list"
                    :key="item.id"
                    :config="item"
                  >
                  </component>

                  <v-transformer ref="transformer" />
                </v-layer>
                <v-layer ref="top-layer">
                  <v-rect
                    ref="selection-box"
                    :config="{
                      fill: 'rgba(0,0,255,0.5)',
                      ...selectionRectangle,
                    }"
                  >
                  </v-rect>
                </v-layer>
              </v-stage>
              <div>
                {{ currentOperationCursor }}
              </div>
              <div>
                {{ operationSequence }}
              </div>
              <div>
                {{ rememberOperation }}
              </div>
            </div>
          </vue-ruler-tool>
        </div>
      </el-main>
      <el-aside>
        <prop-editor
          :bgConfig="stageConfig.bgConfig"
          :selected="selectedShape"
          @change="handleSElementPropChange"
        />
      </el-aside>
    </el-container>
    <el-footer>
      <el-row>
        <el-col :span="2"> 缩放比例 </el-col>
        <el-col :span="3">
          <el-slider v-model="zoom"></el-slider>
        </el-col>
      </el-row>
    </el-footer>
    <context-menu
      :show="rightMenu.show"
      :y="rightMenu.y"
      :x="rightMenu.x"
      @menuitemclick="handleMenuItemClick"
    />
  </el-container>
</template>
<script>
//import Konva from 'konva';
import VueRulerTool from "@/components/ruler/vue-ruler-tool";
import Tools from "@/components/tools/Tools";
import Logo from "@/components/logo/Logo";
import PropEditor from "@/components/prop-editor/PropEditor";
import ContextMenu from "@/components/context-menu/ContextMenu";
import {
  UUID,
  frontMove,
  backMove,
  topMove,
  bottomMove,
  collisionDetect,
} from "@/utils/index";
// eslint-disable-next-line no-unused-vars
import _ from "lodash";

const width = 1000;
const height = 600;
const defaultStageConfig = {
  //所有元素列表
  list: [],
  //背景配置
  bgConfig: {
    bgColor: null,
  },
};

export default {
  name: "Design",
  components: {
    "vue-ruler-tool": VueRulerTool,
    Tools,
    Logo,
    PropEditor,
    ContextMenu,
  },
  mounted () {
    //注册拖拽放置事件
    this.registerToolItemDropEvent();
  },
  data () {
    return {
      //前进后退功能
      //前进后退游标
      currentOperationCursor: 0,
      //前进后退操作序列
      operationSequence: [{ stageConfig: _.cloneDeep(defaultStageConfig) }],
      //是否前进后退案件
      rememberOperation: true,

      //当前选择
      selectedAnchorIndex: -1,
      selectedShapeId: null,

      rangeSelectedIdList: [],
      //蓝色框选区域
      selectionRectangle: {
        tmpx: 0,
        tmpy: 0,
        x: 0,
        y: 0,
        width: 0,
        height: 0,
        visible: false,
      },

      //舞台配置
      stageConfig: {
        ..._.cloneDeep(defaultStageConfig),
      },

      //正在拖拽的工具
      draggingToolItem: null,

      //右键菜单
      rightMenu: {
        show: false,
        y: 0,
        x: 0,
      },

      configKonva: {
        width: width,
        height: height,
      },
      ruler: {
        presetLine: [
          { type: "h", site: 200 },
          { type: "v", site: 100 },
        ],
        visible: true,
      },
      zoom: 100,
    };
  },
  computed: {
    //当前选中的图形用于编辑其内部的属性
    selectedShape () {
      return this.stageConfig.list.find((s) => s.id === this.selectedShapeId);
    },
  },
  methods: {
    //区块中包含的代码将不会被记录于历史记录之中(用户撤回重做操作)
    async unRemember (fn) {
      // eslint-disable-next-line no-unused-vars
      return new Promise((resolve, reject) => {
        const origin = this.rememberOperation;
        this.rememberOperation = false;
        window.setTimeout(() => {
          fn();
          window.setTimeout(() => {
            this.rememberOperation = origin;
            window.setTimeout(() => {
              resolve()
            }, 0)
          }, 0);
        }, 0);
      })
    },
    //后退
    goBack () {
      if (Math.abs(this.currentOperationCursor) < (this.operationSequence.length - 1)) {
        this.unRemember(() => {
          this.currentOperationCursor = this.currentOperationCursor - 1;
          const index =
            this.operationSequence.length -
            Math.abs(this.currentOperationCursor) -
            1;

          this.stageConfig = _.cloneDeep(
            this.operationSequence[index].stageConfig
          );
          this.clearAllSelection(); //仅可清除变形框,不可动其他元数据否则会造成混乱
        });
      }
    },
    //前进
    goFront () {
      if (Math.abs(this.currentOperationCursor) > 0) {
        this.unRemember(() => {
          this.currentOperationCursor = this.currentOperationCursor + 1;
          const index =
            this.operationSequence.length -
            Math.abs(this.currentOperationCursor) -
            1;

          this.stageConfig = _.cloneDeep(
            this.operationSequence[index].stageConfig
          );
          this.clearAllSelection(); //仅可清除变形框,不可动其他元数据否则会造成混乱
        })
      }
    },
    //注册工具栏物件放置事件
    registerToolItemDropEvent () {
      const container = this.getStage().container();
      container.addEventListener("dragover", (e) => {
        e.preventDefault();
      });
      container.addEventListener("drop", this.handleToolItemDrop);
    },
    //点击按钮输出配置JSON
    writeJson () {
      console.log(JSON.stringify(this.stageConfig.list));
    },
    //获取舞台
    getStage () {
      const stage = this.$refs["stage"].getNode();
      return stage;
    },
    //添加图形元素
    addSElement (initialConfig, position) {
      const id = UUID();
      const { xType, x, y, name, ...otherProps } = initialConfig;
      this.stageConfig.list.push({
        xType: xType,
        id: id,
        name: name ?? "graphic-element", //顶级元素
        draggable: true,
        x: position?.x ?? x ?? 0, //默认横纵坐标都为0
        y: position?.y ?? y ?? 0,
        ...otherProps,
      });
    },
    //工具栏开始拖拽
    handleToolItemDragStart (category, item) {
      console.log("工具栏开始拖拽");
      this.draggingToolItem = {
        category,
        item,
      };
    },
    //拖拽事件结束
    handleToolItemDrop (e) {
      console.log("结束拖拽事件");
      //正在拖拽的工具元素不可为null,增加健壮性
      if (this.draggingToolItem) {
        const stage = this.getStage();
        stage.setPointersPositions(e);
        const position = stage.getPointerPosition();
        this.addSElement(this.draggingToolItem.item.initial, position);
        this.draggingToolItem = null;
      }
    },
    //双击工具栏向舞台添加元素组件
    handleToolItemDblClick (category, item) {
      console.log("双击添加元素");
      console.log(category, item);
      this.addSElement(item.initial, null);
    },
    //是否可移动的鼠标手势变换(移入元素)
    handleSElementMoveEnter (e) {
      //是否允许拖拽
      const canDrag = e.target.attrs.draggable;
      const stage = e.target.getStage();
      if (canDrag) {
        stage.container().style.cursor = "move";
      } else {
        stage.container().style.cursor = "not-allowed";
      }
    },

    //是否可移动的鼠标手势变换(移出元素)
    handleSElementMoveLeave (e) {
      const stage = e.target.getStage();
      stage.container().style.cursor = "default";
    },
    //同步移动参数
    handleSElementDragend (e) {
      const shape = this.stageConfig.list.find((r) => r.id === e.target.id());
      // 更新新的坐标
      shape.x = e.target.x();
      shape.y = e.target.y();
    },
    //同步变形参数
    handleSElementTransformEnd (e) {
      const shape = this.stageConfig.list.find((r) => r.id === e.target.id());
      //更新变形候得坐标和对应的缩放比例
      shape.x = e.target.x();
      shape.y = e.target.y();
      shape.rotation = e.target.rotation();
      shape.scaleX = e.target.scaleX();
      shape.scaleY = e.target.scaleY();
      shape.skewX = e.target.skewX();
      shape.skewY = e.target.skewY();
    },

    //刷新变换框
    refreshTransformer () {
      const transformerNode = this.$refs.transformer.getNode();
      //强制更新变换框
      transformerNode.forceUpdate();
    },
    //处理元素的属性输入(修改),只要元素属性输入了或者变化了则会立刻触发此函数更新
    handleSElementPropChange () {
      //重置变换框以适应元素大小变形变换后的新变换框
      window.setTimeout(() => {
        this.refreshTransformer();
      }, 0);
    },
    //统一自定义时间上浮处理机制
    handleSElementEvents (type, ...p) {
      switch (type) {
        case "changepoints":
          this.handleBrokenLineChangePoints(...p);
          break;
        case "selectanchor":
          this.handleBrokenLineSelectAnchor(...p);
          break;
        default:
          break;
      }
    },
    //线段锚点更新上浮函数
    handleBrokenLineChangePoints (id, points) {
      console.log("测试是否接收到了调用");
      const shape = this.stageConfig.list.find((r) => r.id === id);
      shape.points = [...points];
    },
    //线段选择锚点更新上浮函数
    handleBrokenLineSelectAnchor (index) {
      this.selectedAnchorIndex = index;
    },

    //显示右键菜单
    openRightMenu (x, y) {
      this.rightMenu.show = true;
      this.rightMenu.x = x;
      this.rightMenu.y = y;
    },
    //重置右键菜单
    closeRightMenu () {
      //重置右键菜单
      this.rightMenu.show = false;
      this.rightMenu.y = 0;
      this.rightMenu.x = 0;
    },

    //右键显示菜单
    handleStageContextMenu (e) {
      console.log("此处右键最后执行");

      //取消默认的右键显示
      e.evt.preventDefault();

      //若点击得目标是舞台的空白处则关闭右键菜单
      const stage = e.target.getStage();

      // if (e.target === stage) {
      //   //取消显示
      //   this.closeRightMenu();
      //   return;
      // }

      //获得右键菜单的显示坐标
      const containerRect = stage.container().getBoundingClientRect();
      const x = containerRect.left + stage.getPointerPosition().x + 4;
      const y = containerRect.top + stage.getPointerPosition().y + 4;

      //显示右键菜单
      this.openRightMenu(x, y);
    },

    //设置选定组件是否可以拖拽
    setDraggable (draggable) {
      if (this.selectedShapeId) {
        let shape = this.stageConfig.list.find(
          (l) => l.id === this.selectedShapeId
        );
        if (shape) {
          shape.draggable = draggable;
        }
      } else if (this.rangeSelectedIdList.length > 0) {
        this.stageConfig.list
          .filter((l) => this.rangeSelectedIdList.some((rid) => rid === l.id))
          .forEach((shape) => {
            shape.draggable = draggable;
          });
      }
    },

    //锁定组件
    lock () {
      this.setDraggable(false);
    },
    //解锁组件
    unlock () {
      this.setDraggable(true);
    },
    //上移一层
    moveUp () {
      if (this.selectedShapeId) {
        const currentIndex = this.stageConfig.list.findIndex(
          (l) => l.id === this.selectedShapeId
        );
        this.stageConfig.list = backMove(this.stageConfig.list, currentIndex);
      }
    },
    //下移组件
    moveDown () {
      if (this.selectedShapeId) {
        const currentIndex = this.stageConfig.list.findIndex(
          (l) => l.id === this.selectedShapeId
        );
        this.stageConfig.list = frontMove(this.stageConfig.list, currentIndex);
      }
    },
    //移到顶层
    moveTop () {
      if (this.selectedShapeId) {
        const currentIndex = this.stageConfig.list.findIndex(
          (l) => l.id === this.selectedShapeId
        );
        this.stageConfig.list = topMove(this.stageConfig.list, currentIndex);
      }
    },
    //移到底层
    moveBottom () {
      if (this.selectedShapeId) {
        const currentIndex = this.stageConfig.list.findIndex(
          (l) => l.id === this.selectedShapeId
        );
        this.stageConfig.list = bottomMove(this.stageConfig.list, currentIndex);
      }
    },

    //克隆相应组件
    cloneComponent () {
      //单选
      if (this.selectedShapeId) {
        const selectedShape = this.stageConfig.list.find(
          (l) => l.id === this.selectedShapeId
        );
        //选择图形
        if (selectedShape) {
          const newId = UUID();
          // eslint-disable-next-line no-unused-vars
          const { id, x, y, ...otherProps } = selectedShape;
          this.stageConfig.list.push({
            id: newId,
            x: x + 10,
            y: y + 10,
            ...otherProps,
          });
          //设定选中新的图形对象
          window.setTimeout(() => {
            const stage = this.getStage();
            const shape = stage.findOne("#" + newId);
            if (shape && shape.id()) {
              this.unRemember(() => {
                this.setOneSelection(shape);
              })
            }
          }, 0);
        }
      } else if (this.rangeSelectedIdList.length > 0) {
        let newIdList = []; //新的Id数组
        //多选
        for (let rid of this.rangeSelectedIdList) {
          const selectedShape = this.stageConfig.list.find((l) => l.id === rid);
          //选择图形
          if (selectedShape) {
            const newId = UUID();
            // eslint-disable-next-line no-unused-vars
            const { id, x, y, ...otherProps } = selectedShape;
            this.stageConfig.list.push({
              id: newId,
              x: x + 10,
              y: y + 10,
              ...otherProps,
            });
            //新Id的列表集合
            newIdList.push(newId);
          }
        }
        //设定选中新的图形对象集合
        window.setTimeout(() => {
          const stage = this.getStage();
          const shapes = newIdList
            .map((id) => stage.findOne("#" + id))
            .filter((s) => s && s.id());
          if (shapes.length > 0) {
            this.unRemember(() => {
              this.setMultipleSelection([...shapes]);
            })
          }
        }, 0);
      }
    },

    //删除对应的组件元素
    removeComponent () {
      //单选
      if (this.selectedShapeId) {
        const currentIndex = this.stageConfig.list.findIndex(
          (l) => l.id === this.selectedShapeId
        );
        this.stageConfig.list.splice(currentIndex, 1);
      } else if (this.rangeSelectedIdList.length > 0) {
        //多选
        for (let rid of this.rangeSelectedIdList) {
          const currentIndex = this.stageConfig.list.findIndex(
            (l) => l.id === rid
          );
          this.stageConfig.list.splice(currentIndex, 1);
        }
      }
      //删除所有选中调整形状的框框
      this.clearAllSelection();
    },

    //删除对应图形的锚点
    removeAnchor () {
      //选中的图形
      let selectedShape = this.stageConfig.list.find(
        (l) => l.id === this.selectedShapeId
      );
      if (selectedShape?.xClass === "BrokenLine") {
        console.log("选择图形的锚点", selectedShape.points);
        //大于2*3也就是6个points也就是3个点的时候
        if (
          this.selectedAnchorIndex !== -1 &&
          selectedShape.points.length >= 2 * 3
        ) {
          //删除锚点
          selectedShape.points.splice(this.selectedAnchorIndex, 2);
          this.selectedAnchorIndex = -1; //删除锚点后需要把选中的锚点回-1若还要删除则应该重新选择
        } else {
          //锚点不可删除
          console.log("锚点不可删除");
        }
      }
    },

    //右键点击选择的操作
    handleMenuItemClick (action) {
      //点击的右键按钮action
      console.log(`选择了${action}操作`);
      switch (action) {
        case "lock": //锁定
          this.lock();
          break;
        case "unlock": //解锁
          this.unlock();
          break;
        case "moveUp": //上移一层
          this.moveUp();
          break;
        case "moveDown": //下移一层
          this.moveDown();
          break;
        case "moveTop": //置顶
          this.moveTop();
          break;
        case "moveBottom": //置底
          this.moveBottom();
          break;
        case "cloneComponent": //复制组件(元素)
          this.cloneComponent();
          break;
        case "removeComponent": //删除组件(元素)
          this.removeComponent();
          break;
        case "removeAnchor": //删除锚点
          this.removeAnchor();
          break;
        default:
          break;
      }
      //关闭右键菜单
      this.closeRightMenu();
    },
    //鼠标按下开启范围选择
    handleStageMouseDown (e) {
      //点击舞台空白处启用拖拽框选范围选择
      //若点击的不是舞台空白处则不可开启范围选择
      const stage = e.target.getStage();
      if (e.target === stage) {
        console.log("按下鼠标拖拽开启范围选择");
        const x1 = stage.getPointerPosition().x;
        const y1 = stage.getPointerPosition().y;
        this.selectionRectangle = {
          tmpx: x1,
          tmpy: y1,
          x: x1,
          y: y1,
          width: 0,
          height: 0,
          visible: true,
        };
        return;
      }
    },
    //范围选择拖拽
    handleStageMouseMove (e) {
      // 若未按下鼠标则说明未开始拖拽则返回
      if (!this.selectionRectangle.visible) {
        return;
      }
      const stage = e.target.getStage();
      const x1 = this.selectionRectangle.tmpx;
      const y1 = this.selectionRectangle.tmpy;
      const x2 = stage.getPointerPosition().x;
      const y2 = stage.getPointerPosition().y;
      this.selectionRectangle.x = Math.min(x1, x2);
      this.selectionRectangle.y = Math.min(y1, y2);
      this.selectionRectangle.width = Math.abs(x2 - x1);
      this.selectionRectangle.height = Math.abs(y2 - y1);
    },

    //范围选择抬起鼠标
    async handleStageMouseUp (e) {
      console.log("此处重要需要定位如何选择元素");
      const stage = e.target.getStage();
      //关闭所有右键菜单rightMenu
      this.closeRightMenu();
      //多选或者单选或者取消
      //选择框可见的情况下
      //鼠标点下开启范围选择
      if (this.selectionRectangle.visible) {
        //选择框(这里是为了方便使用内置的碰撞检测方法)
        const selectionBox = this.$refs["selection-box"].getNode();
        if (selectionBox) {
          //所有选中的元素
          let selectedShapes = this.stageConfig.list
            .filter((s) => s.xClass !== "BrokenLine")
            .map((s) => stage.findOne("#" + s.id))
            .filter((s) => s && s.id()) //过滤掉所有的空和id为空的元素,增加健壮性
            .filter((s) => collisionDetect(s, selectionBox));
          //若存在选中元素则对他们进行变换
          if (selectedShapes.length >= 2) {
            await this.unRemember(() => {
              //若选择了多个元素则应该清空当前的唯一选择元素
              console.log(selectedShapes, "多选定");
              this.setMultipleSelection(selectedShapes);
            });
          } else if (selectedShapes.length === 1) {
            await this.unRemember(() => {
              //设定一个特殊选择
              console.log(selectedShapes[0], "单选定");
              this.setOneSelection(selectedShapes[0]);
            })
          } else {
            await this.unRemember(() => {
              //一个都没选中 则应该清空选中;
              console.log("清空");
              this.clearAllSelection();
            })
          }
        }
      } else {
        //未开启范围选择
        if (e.target !== stage) {
          //设定一个特殊选择
          //此处需要排除变形或者拖拽带来的问题
          let selectedTarget = e.target;
          //若存在group则e.target为内部元素此函数将目标改为顶层元素
          while (
            selectedTarget.getParent().attrs.xClass !== "XLayer" &&
            selectedTarget.getParent().className !== "Transformer"
          ) {
            selectedTarget = selectedTarget.getParent();
          }
          //鼠标右键且当前点击元素正在位于正在多选元素之中则不选择
          if (
            e.evt.button === 2 &&
            this.rangeSelectedIdList.includes(selectedTarget.id())
          ) {
            //右键且多选则不选择(当前元素位于多选元素之中,即右键点击了正在多选元素中的元素则不做任何操作)
            //佛则需要进一步判断是否需要设定元素单选项
            //
          } else {
            //非右键
            console.log(selectedTarget.getParent(), "selectedParent");
            //若此元素已在变形说明已选择不可重复选中
            if (selectedTarget.getParent().className === "Transformer") {
              //已经在变形的元素不需要处理
            } else {
              //避免重复选择
              if (selectedTarget.id() !== this.selectedShapeId) {
                console.log(selectedTarget, "单选定");
                await this.unRemember(() => {
                  this.setOneSelection(selectedTarget);
                })
              }
            }
          }
        }
      }
      //框选完毕将蓝色鼠标选择框隐藏
      window.setTimeout(() => {
        this.selectionRectangle.visible = false;
      }, 0);
    },

    //清除所有的线段选择
    clearLineSelection () {
      const lines = this.stageConfig.list.filter(
        (l) => l.xClass === "BrokenLine"
      );
      for (let l of lines) {
        l.trans = false;
      }
    },
    //清空所有图形的变换框效果
    clearTransformer () {
      const transformerNode = this.$refs.transformer.getNode();
      transformerNode.nodes([]);
    },
    //清除所有的选择
    clearAllSelection () {
      this.selectedShapeId = null;
      this.selectedAnchorIndex = -1;
      this.rangeSelectedIdList = [];
      this.clearLineSelection();
      this.clearTransformer();
    },
    //设置变形
    setTransformer (nodes) {
      const transformerNode = this.$refs.transformer.getNode();
      transformerNode.nodes([...nodes]);
    },
    // //设置单选选中
    // setOneSelection (selection) {

    //   // clicked on transformer - do nothing
    //   const clickedOnTransformer =
    //     selectedTarget.getParent().className === 'Transformer';
    //   if (clickedOnTransformer) {
    //     return;
    //   }

    //   // find clicked shape by its id
    //   const id = selectedTarget.id();
    //   const shape = this.list.find((r) => r.id === id);
    //   if (shape) {
    //     this.selectedShapeId = id;
    //   } else {
    //     this.clearSelection();
    //   }

    //   if ((selectedTarget.attrs.className === 'FlowLine') || (selectedTarget.attrs.className === 'SolidLine')) {
    //     //若是FlowLine则不需要调用变形组件
    //     //清除所有图形的变形选择效果
    //     this.clearAllShapeTransformerSelection();
    //     //这里可以做显示隐藏锚点处理
    //     shape.trans = true;//显示变换锚点

    //   } else {
    //     //清除所有图形的变形选择效果
    //     this.clearAllShapeTransformerSelection();
    //     //更新图形选择框
    //     this.updateTransformer();
    //   }
    // },

    //设置单选
    setOneSelection (selection) {
      this.clearAllSelection();

      this.selectedShapeId = selection.id();
      //这里需要区分线段和普通图形
      if (selection.attrs.xClass === "BrokenLine") {
        let line = this.stageConfig.list.find((l) => l.id === selection.id());
        if (line) {
          line.trans = true;
        }
      } else {
        this.setTransformer([selection]);
      }
    },

    //设置多选中
    setMultipleSelection (selectionList) {
      this.clearAllSelection();

      this.rangeSelectedIdList = [...selectionList.map((s) => s.id())];
      this.setTransformer([...selectionList]);
    },

    // //清除所有图形的变形选择效果
    // clearAllShapeTransformerSelection () {
    //   //清空所有线段的线选择效果
    //   this.clearLineSelection();
    //   //清空所有图形的变换框效果
    // },

    // //设置拖拽变形
    // updateTransformer () {
    //   // here we need to manually attach or detach Transformer node
    //   const transformerNode = this.$refs.transformer.getNode();
    //   const stage = transformerNode.getStage();
    //   const { selectedShapeId } = this;
    //   //若未明确的赋予元素id则元素的id为空字符串
    //   //findOne('#')和find('#')方法将能够查询出这些元素引起严重bug所以此处若未选择selectedShapeId=null则可避免这些问题
    //   //为增加程序的健壮性此处若发现selectedShapeId为null、undefined或''则说明未选择任何元素则直接取消变形操作。
    //   if (!selectedShapeId) {
    //     // remove transformer
    //     transformerNode.nodes([]);
    //     return;
    //   }
    //   const selectedNode = stage.findOne('#' + selectedShapeId);
    //   // do nothing if selected node is already attached
    //   if (selectedNode === transformerNode.node()) {
    //     return;
    //   }
    //   if (selectedNode) {
    //     // attach to another node
    //     transformerNode.nodes([selectedNode]);
    //   } else {
    //     // remove transformer
    //     transformerNode.nodes([]);
    //   }
    // },

    //存储操作序列
    storeOperation (_stageConfig) {
      //存储
      if (this.currentOperationCursor === 0) {
        this.operationSequence.push({
          stageConfig: _.cloneDeep(_stageConfig),
        });
      } else {
        //注意存储并从游标处截断
        const start =
          this.operationSequence.length - Math.abs(this.currentOperationCursor);
        const length = Math.abs(this.currentOperationCursor);
        this.operationSequence.splice(start, length);
        this.operationSequence.push({
          stageConfig: _.cloneDeep(_stageConfig),
        });
        this.currentOperationCursor = 0;
      }
    },
  },
  watch: {
    visible (val) {
      console.log(val);
    },
    //此处监听list变化即可做后退操作
    stageConfig: {
      deep: true,
      // eslint-disable-next-line no-unused-vars
      handler (val, oldVal) {
        //是否开启记住记录操作开关
        if (this.rememberOperation) {
          this.storeOperation(val);
        }
      },
    },
  },
};
</script>

<style lang="scss" scoped>
.top-title {
  height: 60px;
  line-height: 60px;
  margin-left: 50px;
  font-size: 20px;
  font-weight: bold;
}

.el-container {
  height: 100%;
}

.el-header {
  height: 50px;
  border-bottom: 1px solid #cccccc;
}
.el-aside {
  border-right: 1px solid #cccccc;
}
.el-footer {
  height: 30px;
  border-top: 1px solid #cccccc;
}

.el-main {
  background-color: #bbb;
}

.scale-ruler {
  width: 100%;
  height: 100%;
}

.scada-canvas {
  margin: 10px;
  background-color: #fff;
  border: 1px solid #999;
  position: relative;
  box-shadow: 1px 1px 5px #999;

  transform-origin: left top;
  width: 1000px;
  height: 600px;
  background: rgb(255, 255, 255);

  background: #fff
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%202%202%22%3E%3Cpath%20d%3D%22M1%202V0h1v1H0v1z%22%20fill-opacity%3D%22.05%22%2F%3E%3C%2Fsvg%3E") !important;
  background-size: 16px 16px !important;
  transition: background-color 0.2s ease-in-out;
}
</style>
<style lang="scss" scoped>
@use "sass:math";
/*缩放处理*/
@for $i from 0 through 100 {
  .scale-#{$i} {
    transform: scale(math.div($i, 100));
  }
}
</style>